using NUnit.Framework;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Unity.Entities;
using Unity.Entities.UniversalDelegates;
using Unity.VisualScripting;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.Windows;

namespace EntitiesView.Editor
{
    public class EntityViewerConfig : ScriptableObject
    {
        static EntityViewerConfig m_instance;
        public static EntityViewerConfig Instance
        {
            get
            {   if(m_instance == null)
                {
                    var path = Path;
                    var assetPath = "Assets/EntitiesViewer/Editor/EntityViewerConfig.asset";
                    var settings = AssetDatabase.LoadAssetAtPath<EntityViewerConfig>(assetPath);
                    if (settings == null)
                    {
                        settings = CreateInstance<EntityViewerConfig>();
                        AssetDatabase.CreateAsset(settings, assetPath);
                    }
                    m_instance = settings;
                }
                return m_instance;
            }
        }

        public static string Path
        {
            get
            {
                var path = Application.dataPath;
                path = $"{path}/EntitiesViewer/Editor";
                if (!System.IO.Directory.Exists(path))
                {
                    System.IO.Directory.CreateDirectory(path);
                    AssetDatabase.Refresh();
                }
                return path;
            }
        }

        public static Type[] IBuffElementTypes()
        {
            List<Type> list = new List<Type>();
            if (Instance.loadAssemblyCSharp)
            {
                string assemblyPath = Application.dataPath.Substring(0, Application.dataPath.Length - 6);
                Assembly assembly  = System.Reflection.Assembly.LoadFile($"{assemblyPath}/Library/ScriptAssemblies/Assembly-CSharp.dll");
                PushTypes(assembly, typeof(IBufferElementData), list);
            }
            // ReSharper disable once ForCanBeConvertedToForeach
            for (int i = 0; i < Instance.targetAssemblies.Length; ++i)
            {
                var item = Instance.targetAssemblies[i];
                if(item==null)
                    continue;
                string assemblyName = item.name;
                Assembly assembly = Assembly.Load(assemblyName);
                PushTypes(assembly, typeof(IBufferElementData), list);
            }
            return list.ToArray();
        }

        static void PushTypes(Assembly assembly, Type targetInterType,List<Type> list)
        {
            var types = assembly.GetTypes();
            string typeName = targetInterType.FullName;
            for (int j = 0; j < types.Length; j++)
            {
                var type = types[j];
                if(type.IsStruct())
                {
                    var interfaces = type.GetInterfaces();
                    for(int i = 0;i < interfaces.Length;++i)
                    {
                        if (!string.IsNullOrEmpty(interfaces[i].FullName) && interfaces[i].FullName.Equals(typeName))
                        {
                            list.Add(type);
                        }
                    }
                }
            }
        }

        public static Type[] ComponentDataTypes()
        {
            List<Type> list = new List<Type>();
            if (Instance.loadAssemblyCSharp)
            {
                string assemblyPath = Application.dataPath.Substring(0, Application.dataPath.Length - 6);
                Assembly assembly = System.Reflection.Assembly.LoadFile($"{assemblyPath}/Library/ScriptAssemblies/Assembly-CSharp.dll");
                PushTypes(assembly, typeof(IComponentData), list);
            }
            // ReSharper disable once ForCanBeConvertedToForeach
            for (int i = 0; i < Instance.targetAssemblies.Length; ++i)
            {
                var item = Instance.targetAssemblies[i];
                if (item == null)
                    continue;
                string assemblyName = item.name;
                Assembly assembly = Assembly.Load(assemblyName);
                PushTypes(assembly, typeof(IComponentData), list);
            }
            return list.ToArray();
        }

        public static string GetScriptPathFromInstance(ScriptableObject scriptInstance)
        {
            // 获取这个实例的MonoScript对象
            MonoScript monoScript = MonoScript.FromScriptableObject(scriptInstance);
            // 使用AssetDatabase获取路径
            string path = AssetDatabase.GetAssetPath(monoScript);
            return path;
        }
        [Serializable]
        struct Content
        {
            public string TargetType;
            public string Param;
        }
       
        [SerializeField]
        [Space(10)]
        Content[] contents;
        [SerializeField]
        string defaultString;

        [SerializeField] private bool loadAssemblyCSharp = true;
        [SerializeField] private AssemblyDefinitionAsset[] targetAssemblies;
        public string Codition(Type type)
        {
            string typeName = type == null ? "" : type.FullName;
            // ReSharper disable once ForCanBeConvertedToForeach
            for(int i = 0;i < contents.Length; ++i)
            {
                var item = contents[i];
                if(!string.IsNullOrEmpty(typeName) && typeName.Equals(item.TargetType))
                {
                    return item.Param;
                }    
            }
            return defaultString;
        }
    }
}

